﻿using System;
using System.Windows.Forms;
using LightEngine.MessbauerCore.MessbauerData;

namespace LightEngine
{
    namespace SpectrumControling
    {
        /// <Описание перечисления public enum TransformParamsIndexes>
        /// Перечисление содержит типы возможных преобразований спектра
        /// TypeOfTransformation - тип проводимого преобразования из TransformationTypes
        /// Parameter1 - параметр преобразования
        ///              для StrippingMethod это коэффициент масштабирования спектра получ. в результате
        ///              для ScalingMethod это коэффициент сжатия спектра
        /// ScalingMethod - изменение представления спектра
        /// </Описание перечисления public enum TransformParamsIndexes>
        public enum TransformParamsIndexes
        {
            TypeOfTransformation = 0,
            Parameter1 = 1
        };


        /// <описание класса public class DataController>
        /// Версия класса 1.0.1
        /// Класс предназначен для управления загрузкой файлов-спектров в память, управления 
        /// преобразованиями над спектрами и сохранение изменений спектров в истории преобразований с
        /// последующим извлечением спектров из истории.
        /// Элементы класса:
        /// 1. Константы класса:
        /// а) public const UInt16 NumOfTransformationParameters = 2; максимальное число аргументов, 
        ///    необходимых для преобразования мессбауэровского спектра.
        /// 2. Поля класса:
        /// а) private MessbSpectrum MSpectrum = new MessbSpectrum(); текущий (активно используемый) 
        ///    мессбауэровский спектр.
        /// б) private Boolean SuccessfullyTransformed = false; индикатор успешно проведенных 
        ///    преобразований, равен true в случае если преобразования прошли удачно.
        /// в) private ActionMemento SpectrumMemento = new ActionMemento(); хранитель истории 
        ///    преобразований текущего (активного) мессбауровского спектра MSpectrum.
        /// 3. Методы класса:
        /// а) public DataController() конструктор класса, ничего не делает.
        /// б) public Boolean TransformSpectrum(String FirstSpec, String SecondSpec,
        ///                                     params UInt32[] ParamsArray) 
        ///    проведение преобразований спектров, расположенных в файловой системе FirstSpec и SecondSpec,
        ///    в зависимости от типа преобразований:
        ///    - если тип преобразования InvertingMethod либо ScalingMethod, то путь к преобразуемому 
        ///      спектру содержится в FirstSpec, а SecondSpec равен String.Empty,
        ///    - если тип преобразования StrippingMethod то обе переменные содержат пути к спектрам
        ///    ParamsArray содержит параметры преобразований, записанные по индексам 
        ///    TransformParamsIndexes. В случае если преобразование выполнить возможно MSpectrum принимает
        ///    результат проведенных преобразований, в противном случае не меняет значение.
        /// в) public void LoadSpectrumFile(String FileName) загрузка спектра из файла String FileName, 
        ///    если спектр загрузить невозможно, это  метод никак не уведомляет об этом. При открытии
        ///    осуществляется очистка истории преобразованийй мессбауэровского спеектра MSpectrum.
        /// г) public void SaveSpectrumToFile(String FileName) сохранение спектра в файл String FileName.
        /// д) private void UseRemembedSpec() загрузка из хранителя SpectrumMemento  спектра с индексом,
        ///    используемого спектра в хранителе (внутрренняя переменная SpectrumMemento).
        /// е) public void RememberState(MessbSpectrum CurrentSpectrum) сохранении Мессбауэровского 
        ///    спектра, задаваемого в аргументе CurrentSpectrum в AppActionsMemory, если история пуста
        ///    т.е. StepIndex равен -1, StepIndex получает значение равное 0 (первый элемент в списке 
        ///    истории преобразований).
        /// ж) public void StepUpMementoSpecs() шаг, если такой шаг возможен, вверх по истории 
        ///    преобразований, хранимой в SpectrumMemento.
        /// з) public void StepDownMementoSpecs() шаг, если такой шаг возможен, вниз по истории 
        ///    преобразований, хранимой в SpectrumMemento.
        /// 4. Свойства и индексаторы класса:
        /// а) public MessbSpectrum GetMessbSpec свойтсво только для чтения, возвращает 
        ///    мессбауэровский спектр MSpectrum.
        /// б) public Boolean CanStepUpMementoSpecs свойтсво только для чтения возвращает 
        ///    true, если есть возможность сделать шаг вверх по истории преобразований мессбауэровсого 
        ///    спектра MSpectrum, иначе возвращает false.
        /// в) public Boolean CanStepDownMementoSpecs свойтсво только для чтения возвращает 
        ///    true, если есть возможность сделать шаг вybp по истории преобразований мессбауэровсого 
        ///    спектра MSpectrum, иначе возвращает false.
        /// </описание класса public class DataController>


        public class DataController
        {
            public const UInt16 NumOfTransformationParameters = 2;

            private MessbSpectrum MSpectrum = new MessbSpectrum();
            private Boolean SuccessfullyTransformed = false;
            private ActionMemento SpectrumMemento = new ActionMemento();

            public DataController()
            {

            }

            public MessbSpectrum GetMessbSpec
            {
                get
                {
                    return MSpectrum;
                }
            }

            public Boolean TransformSpectrum(String FirstSpec, String SecondSpec,
                                             params UInt32[] ParamsArray)
            {
                MessbSpectraTransformer Transformator = null;
                MessbSpectrum Spec1 = new MessbSpectrum(),
                              Spec2 = new MessbSpectrum();

                switch (ParamsArray[(UInt16)TransformParamsIndexes.TypeOfTransformation])
                {

                    case (UInt32)TransformationTypes.StrippingMethod:
                        if ((FirstSpec == String.Empty) && (MessbSpectrumLoader.IsSuccessfullyLoaded() == true))
                            Spec1 = MSpectrum;
                        else MessbSpectrumLoader.LoadSpectrumFromFile(FirstSpec, Spec1);
                        if (MessbSpectrumLoader.IsSuccessfullyLoaded() == true)
                        {
                            if ((SecondSpec == String.Empty) && (MessbSpectrumLoader.IsSuccessfullyLoaded() == true))
                                Spec2 = MSpectrum;
                            else MessbSpectrumLoader.LoadSpectrumFromFile(SecondSpec, Spec2);
                            if (MessbSpectrumLoader.IsSuccessfullyLoaded() == true)
                            {
                                Transformator = new MessbSpectraTransformer(new StrippingAlgorithm());
                            }
                        }
                        break;
                    case (UInt32)TransformationTypes.ScalingMethod:
                        if (MessbSpectrumLoader.IsSuccessfullyLoaded() == true)
                        {
                            Transformator = new MessbSpectraTransformer(new ScalingAlgorithm());
                            Spec1 = MSpectrum;
                        }
                        break;
                    case (UInt32)TransformationTypes.InvertingMethod:
                        if (MessbSpectrumLoader.IsSuccessfullyLoaded() == true)
                        {
                            Transformator = new MessbSpectraTransformer(new InvertingAlgorithm());
                            Spec1 = MSpectrum;
                        }
                        break;
                }

                if (Transformator != null)
                {
                    MSpectrum = Transformator.DoTransformation(Spec1, Spec2,
                                                                 ParamsArray[(UInt16)TransformParamsIndexes.Parameter1],
                                                                 ref SuccessfullyTransformed);
                    if (MSpectrum != null)
                    {
                        MSpectrum.CalculateParameters(true);
                        SpectrumMemento.RememberState(MSpectrum);
                    }
                }
                return SuccessfullyTransformed;
            }

            public void LoadSpectrumFile(String FileName)
            {
                SpectrumMemento.TruncateRemembedSpecs();
                MessbSpectrumLoader.LoadSpectrumFromFile(FileName, MSpectrum);
                if (MessbSpectrumLoader.IsSuccessfullyLoaded() == true)
                {
                    MSpectrum.CalculateParameters(true);
                    SpectrumMemento.RememberState(MSpectrum);
                }
            }
            public void SaveSpectrumToFile(String FileName)
            {
                MessbSpectrumLoader.LoadSpectrumToFile(FileName, MSpectrum);
            }

            private void UseRemembedSpec()
            {
                MSpectrum = SpectrumMemento.PointedMessbSpectrum;
            }

            public Boolean SpectrumPresent
            {
                get { return SpectrumMemento.HasMementoRecords; }
            }

            public void StepUpMementoSpecs()
            {
                if (SpectrumMemento.StepForward() == true)
                    UseRemembedSpec();
            }

            public void StepDownMementoSpecs()
            {
                if (SpectrumMemento.StepBack() == true)
                    UseRemembedSpec();
            }

            public Boolean CanStepUpMementoSpecs
            {
                get
                {
                    return SpectrumMemento.CanStepForward();
                }
            }

            public Boolean CanStepDownMementoSpecs
            {
                get
                {
                    return SpectrumMemento.CanStepBack();
                }
            }
        }
    }
}
